<html>
    <head>
        <title>创建编译服务</title>
    </head>
    <body>
        <script>
            /*

                    二、、创建编译服务

                                创建一个服务类来处理代码编译和执行，下面是一个示例：

                                eg:
                                    using System;
                                    using System.Collections.Generic;
                                    using System.IO;
                                    using System.Linq;
                                    using System.Reflection;
                                    using System.Runtime.Loader;
                                    using System.Threading.Tasks;
                                    using Microsoft.CodeAnalysis;
                                    using Microsoft.CodeAnalysis.CSharp;
                                    using Microsoft.CodeAnalysis.Emit;
                                    using Volo.Abp.DependencyInjection;


                                    namespance YourNamespace
                                    {
                                        public class DynamicCompilerService:ITransientDependency
                                        {
                                            private readonly  List<MetadataReference> _references = new List<MetadataReference>();

                                            public DynamicCompilerService()
                                            {
                                                AddDefaultReferences(); // 添加默认引用
                                            }

                                            private void AddDefaultReferences()
                                            {
                                                // 添加.net 标准库引用
                                                AddReference(typeof(object).Assembly);
                                                AddReference(typeof(System.Linq.Enumerable).Assembly);
                                                AddReference(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly);
                                                AddReference(typeof(Volo.Abp.AbpException).Assembly);

                                                // 添加其他可能需要的ABP模块
                                            }


                                            // 对程序集添加引用
                                            public void AddReference(Assembly assembly)
                                            {
                                                _references.Add(MeradataReference.CreateFromFile(assembly.Location));
                                            }


                                            // 动态编译并执行代码
                                            public async Task<object> CompileAndExcuteAsync(string code,string entryMethod = "Execute",params object[] parameters)
                                            {
                                                  // 创建语法树
                                                  SyntaxTree syntaxTree =CSharpSyntaxTree.ParseText(code);
                                                   

                                                  // 创建编译选项
                                                  CSharpCompilationOptions options = new CSharpCompilationOptions(
                                                        OutputKind.DynamicallyLinkedLibrary,
                                                        optimizationLevel: OptimizationLevel.Release,  // 设置优化级别
                                                        allowUnsafe:true
                                                  );

                                                  // 创建编译对象
                                                  CsharpCompilation compilation = CSharpCompilation.Create(
                                                        $"DynamicCompilation_{Guid.NewGuid()}",
                                                        new[] {syntaxTreee},
                                                        _references,
                                                        options
                                                  );


                                                  // 在内存中编译
                                                  using( MemoryStream ms = new MemoryStream())
                                                  {
                                                      EmitResult result = compilation.Emit(ms);  // 触发编译

                                                      if(!result.Success)  // 编译失败    diagnostic:诊断      severity:严重程度，严重性         
                                                      {
                                                          IEnumerable<Diagnostic> failurs = result.Diagnostics.Where(diagnostic=>diagnostic.IsWarnAsError || diagnostic.Severity==DiagnosticSeverity.Error);

                                                          string errorMessage = string.Join(Environment.NewLine,failures.Select(f=>f.toString()));
                                                          
                                                          throw new InvalidOperationException($"动态编译错误：{errorMessage}");
                                                      }


                                                      ms.Seek(0,SeekOrgin.Begin);

                                                      // 加载程序集
                                                      Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);


                                                      // 获取程序集中所有类型
                                                      Type[] types = assembly.GetTypes();
                                                      
                                                      // 获取带有名为 "Execute" 方法的类型
                                                      Type entryType = types.FirstOrDefault(t=>t.GetMethod(entryMethod) !=null);

                                                      if(entryType==null)
                                                      {
                                                            throw new InvaliOperationException($"找不到包含'{entryMethod}'方法的类型")
                                                      }

                                                      MethodInfo method = entryType.GetMethod(entryMethod);

                                                      if(method==null)
                                                      {
                                                            throw new InvalidOperationException($"找不到方法'{entryMethod}'")
                                                      }

                                                      // 创建实例并执行方法
                                                      object instance = Activator.CreateInstance(entryType);
                                                      
                                                      return method.Invoke(instance,parameters);
                                                  }
                                            }
                                        }
                                    }
                */
        </script>
    </body>
</html>